package io.github.echarts.model.coordinate.cartesian;

import io.github.echarts.model.geometry.Point;
import io.github.echarts.model.geometry.Rectangle;

/**
 * 笛卡尔坐标系转换器，负责在逻辑坐标和像素坐标之间进行转换
 * 坐标系采用左下角为原点(0,0)，X轴向右为正，Y轴向上为正
 */
public class CartesianCoordinateTransformer {
    /**
     * 坐标系区域
     */
    private Rectangle area;

    /**
     * 创建坐标转换器
     * 
     * @param area 坐标系区域
     */
    public CartesianCoordinateTransformer(Rectangle area) {
        this.area = area;
    }

    /**
     * 将X轴上的相对位置（0-1）转换为像素坐标
     * 
     * @param relativeX X轴相对位置（0表示最左侧，1表示最右侧）
     * @return 对应的像素X坐标
     */
    public double transformX(double relativeX) {
        return area.getX() + relativeX * area.getWidth();
    }

    /**
     * 将Y轴上的相对位置（0-1）转换为像素坐标
     * 
     * @param relativeY Y轴相对位置（0表示最底部，1表示最顶部）
     * @return 对应的像素Y坐标
     */
    public double transformY(double relativeY) {
        // 注意：坐标系原点在左下角，Y轴向上为正
        return area.getY() + relativeY * area.getHeight();
    }

    /**
     * 将坐标转换为点对象
     * 
     * @param relativeX X轴相对位置（0-1）
     * @param relativeY Y轴相对位置（0-1）
     * @return 对应的像素坐标点
     */
    public Point transform(double relativeX, double relativeY) {
        return new Point(transformX(relativeX), transformY(relativeY));
    }

    /**
     * 将像素X坐标转换为相对位置（0-1）
     * 
     * @param pixelX 像素X坐标
     * @return X轴相对位置（0-1）
     */
    public double inverseTransformX(double pixelX) {
        if (area.getWidth() == 0) {
            return 0;
        }
        return (pixelX - area.getX()) / area.getWidth();
    }

    /**
     * 将像素Y坐标转换为相对位置（0-1）
     * 
     * @param pixelY 像素Y坐标
     * @return Y轴相对位置（0-1）
     */
    public double inverseTransformY(double pixelY) {
        if (area.getHeight() == 0) {
            return 0;
        }
        // 注意：坐标系原点在左下角，Y轴向上为正
        return (pixelY - area.getY()) / area.getHeight();
    }

    /**
     * 获取坐标系区域
     * 
     * @return 坐标系区域
     */
    public Rectangle getArea() {
        return area;
    }

    /**
     * 设置坐标系区域
     * 
     * @param area 坐标系区域
     */
    public void setArea(Rectangle area) {
        this.area = area;
    }
} 